/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package core;

import datamodel.Order;
import java.util.Vector;
import network.Connection;
import network.PacketBuilder;
import network.packets.OrderChanged;
import network.packets.Packet;
import view.MainForm;
import view.NewOrderForm;
/**
 *
 * @author Kvest
 */
public class OrderManager 
{
    private static OrderManager manager = null;;
    private static final Object lock = new Object();
    
    private NewOrderNotifier newOrderNotifier;
    private UpdateOrderNotifier updateOrderNotifier;
    private DeleteOrderNotifier deleteOrderNotifier;
    
    private NewOrderForm newOrderForm;
    private NewOrderForm regionOrderForm;
    private NewOrderForm appointedOrderForm;
    
    public static OrderManager getManager()
    {
        synchronized(lock)
        {
            if (manager == null)
            {
                manager = new OrderManager();
            }
        }
        
        return manager;
    }
    
    private Vector orders;
    private boolean ordersGotten;
    private boolean emitEvent;
    
    private OrderManager()
    {
        orders = new Vector();
        ordersGotten = false;
        emitEvent = true;
        
        newOrderNotifier = null;
        updateOrderNotifier = null;
        deleteOrderNotifier = null;
        
        //Регистрируем обработчик пакета изменения заказа
        Connection.getConnection().setPacketListener(Packet.ORDER_CHANGED, new Connection.PacketNotifier() 
        {
            public void incomingPacket(Packet packet) 
            {
                OrderChanged orderChapgedPacket = (OrderChanged)packet;
                
                //Уведомляем сервер что получили заказ
                byte[] data = PacketBuilder.createOrderRecievedResponce(DriverManager.getManager().getDriverID(),
                                                                        orderChapgedPacket.getOrderID(), 
                                                                        orderChapgedPacket.getEvent());
                Connection.getConnection().send(data);
                
                switch(orderChapgedPacket.getEvent())
                {
                    case OrderChanged.EVENT_UPDATE : 
                        updateOrder(orderChapgedPacket.getOrderID(), orderChapgedPacket.getPreviewText(), orderChapgedPacket.getFullText()); 
                        break;
                    case OrderChanged.EVENT_NEW : 
                        newOrder(orderChapgedPacket.getOrderID(), orderChapgedPacket.getPreviewText(),orderChapgedPacket.getFullText(), 
                                 orderChapgedPacket.getOrderType()); 
                        break;
                    case OrderChanged.EVENT_DELETE : 
                        deleteOrder(orderChapgedPacket.getOrderID()); 
                        break;    
                }
            }
        });
    }

    public boolean isOrdersGotten() 
    {
        return ordersGotten;
    }

    public void setOrdersGotten(boolean ordersGotten) 
    {
        this.ordersGotten = ordersGotten;
    }

    public synchronized void addOrder(Order order)
    {
        //Удаляем заказ, если такой есть
        for (int i = orders.size() - 1; i >= 0; --i)
        {
            if (((Order)orders.elementAt(i)).getId() == order.getId())
            {
                orders.removeElementAt(i);
            }
        }   
        
        //Добавляем заказ
        orders.addElement(order);
    }

    public synchronized Pair[] getPreviewList()
    {
        Pair[] result = new Pair[orders.size()];
        for (int i = 0; i < orders.size(); ++i)
        {
            result[i] = new Pair(((Order)orders.elementAt(i)).getId(), ((Order)orders.elementAt(i)).getPreviewText());
        }
        
        return result;
    }
        
    public synchronized Order getOrder(int orderID)
    {
        for (int i = 0; i < orders.size(); ++i)
        {
            if (((Order)orders.elementAt(i)).getId() == orderID)
            {
                return (Order)orders.elementAt(i);
            }
        }
        
        return null;
    }
    
    public synchronized void updateOrder(int orderID, String previewText, String fullText)
    {
        //Проверяем, не текущий ли это заказ
        if (orderID == DriverManager.getManager().getCurrentOrderID())
        {
            //Устанавливаем текущий заказ
            DriverManager.getManager().setCurrentOrderID(orderID);
            DriverManager.getManager().setCurrentOrderText(fullText);
            
            //Обновляем форму
            if (ScreenEngine.getEngine().getCurrent() instanceof MainForm)
            {
                ((MainForm)ScreenEngine.getEngine().getCurrent()).update(true);
            }
        }
        
        for (int i = 0; i < orders.size(); ++i)
        {
            if (((Order)orders.elementAt(i)).getId() == orderID)
            {
                ((Order)orders.elementAt(i)).setPreviewText(previewText);
                ((Order)orders.elementAt(i)).setFullText(fullText);
                
                if (updateOrderNotifier != null)
                {
                    updateOrderNotifier.updateOrder((Order)orders.elementAt(i));
                }
                
                return;
            }
        }
    }
    
    public synchronized void newOrder(int orderID, String previewText, String fullText, int orderType)
    {
        //Удаляем заказ, если такой есть
        for (int i = orders.size() - 1; i >= 0; --i)
        {
            if (((Order)orders.elementAt(i)).getId() == orderID)
            {
                orders.removeElementAt(i);
            }
        }   
        
        //Создаем и добавляем заказ
        Order newOrder = new Order(orderID, previewText, fullText);
        orders.addElement(newOrder);
        
        if (emitEvent)
        {
            if (orderType == OrderChanged.ORDER_TYPE_IN_REGION) {
                //Проигрываем музыку
                MediaManager.getManager().playMusic(Settings.getSettings().getStartOrderMelodyId(), -1);
                        
                //Отображаем форму с заказом для региона
                showRegionOrderForm(newOrder);
            } else if (orderType == OrderChanged.ORDER_TYPE_USUAL) {
                //Проигрываем музыку
                MediaManager.getManager().playMusic(Settings.getSettings().getNewOrderMelodyId());

                //Отображаем форму с заказом
                showNewOrderForm(newOrder);
            } else if (orderType == OrderChanged.ORDER_TYPE_APPOINTED) {
                //Проигрываем музыку
                MediaManager.getManager().playMusic(Settings.getSettings().getStartOrderMelodyId(), -1);
                
                //Отображаем форму с назначенным заказом
                showAppointedOrderForm(newOrder);
            }
        }
        
        //Генерируем событие
        if (newOrderNotifier != null)
        {
            newOrderNotifier.newOrder(newOrder);
        }
    }
    
    private void showAppointedOrderForm(Order order) {
        //Если еще не создали - создаем
        if (appointedOrderForm == null) {
            appointedOrderForm = new NewOrderForm("appointed_order", 0x0000ff, 0xff0000);
        }
        
        //Добавляем заказ
        appointedOrderForm.addOrder(order);
        
        //Отображаем
        if (ScreenEngine.getEngine().getCurrent() != appointedOrderForm)
        {
            ScreenEngine.getEngine().push(appointedOrderForm);
        }
    }
    
    private void showRegionOrderForm(Order order) {
        //Если еще не создали - создаем
        if (regionOrderForm == null) {
            regionOrderForm = new NewOrderForm("order_in_region", 0xffff00, 0x00);
        }
        
        //Добавляем заказ
        regionOrderForm.addOrder(order);
        
        //Отображаем
        if (ScreenEngine.getEngine().getCurrent() != regionOrderForm)
        {
            ScreenEngine.getEngine().push(regionOrderForm);
        }
    }
    
    private void showNewOrderForm(Order order)
    {
        /*
        if ((ScreenEngine.getEngine().getCurrent() instanceof OrderInformationForm) || (ScreenEngine.getEngine().getCurrent() instanceof OrdersListForm))
        {
            return;
        } 
        */ 
        //Если еще не создали - создаем
        if (newOrderForm == null)
        {
            newOrderForm = new NewOrderForm("new_order");
        }
        
        //Добавляем заказ
        newOrderForm.addOrder(order);
        
        //Отображаем
        if (ScreenEngine.getEngine().getCurrent() != newOrderForm)
        {
            ScreenEngine.getEngine().push(newOrderForm);
        }
    }
    
    public synchronized void deleteOrder(int orderID)
    {
        //Удаляем заказ
        for (int i = orders.size() - 1; i >= 0; --i)
        {
            if (((Order)orders.elementAt(i)).getId() == orderID)
            {
                orders.removeElementAt(i);
            }
        } 
        
        if (deleteOrderNotifier != null)
        {
            deleteOrderNotifier.deleteOrder(orderID);
        }
    }

    public DeleteOrderNotifier getDeleteOrderNotifier() 
    {
        return deleteOrderNotifier;
    }

    public void setDeleteOrderNotifier(DeleteOrderNotifier deleteOrderNotifier) 
    {
        this.deleteOrderNotifier = deleteOrderNotifier;
    }

    public NewOrderNotifier getNewOrderNotifier() 
    {
        return newOrderNotifier;
    }

    public void setNewOrderNotifier(NewOrderNotifier newOrderNotifier) 
    {
        this.newOrderNotifier = newOrderNotifier;
    }

    public UpdateOrderNotifier getUpdateOrderNotifier() 
    {
        return updateOrderNotifier;
    }

    public void setUpdateOrderNotifier(UpdateOrderNotifier updateOrderNotifier) 
    {
        this.updateOrderNotifier = updateOrderNotifier;
    }

    public static class Pair
    {
        int id;
        String value;
        
        public Pair(int id, String value)
        {
            this.id = id;
            this.value = value;
        }

        public int getId() 
        {
            return id;
        }

        public String getValue() 
        {
            return value;
        }
    }
    
    public interface NewOrderNotifier
    {
        public void newOrder(Order order);
    }
    
    public interface UpdateOrderNotifier
    {
        public void updateOrder(Order order);
    }
    
    public interface DeleteOrderNotifier
    {
        public void deleteOrder(int orderID);
    }

    public void setEmitNewOrderEvent(boolean emitEvent) 
    {
        this.emitEvent = emitEvent;
    }
}
